package com.bds.btcdc.adapter.huobi.trade.util;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

public class HttpUtilProxy {
	private Logger logger = LoggerFactory.getLogger(getClass());
	private static String SECRET = "3cc75ccda1e8c1310da65313b05467b3215913d789773dfe8866aba1043909b3";
	private static String KEY = "A21E3D10-5423-4A58-BD1F-728A7089871F";

	private static HttpUtilProxy instance = new HttpUtilProxy();
	private static HttpClient client;
	private static long startTime = System.currentTimeMillis();
	public static PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
	private static ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy() {

		public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
			long keepAlive = super.getKeepAliveDuration(response, context);

			if (keepAlive == -1) {
				keepAlive = 5000;
			}
			return keepAlive;
		}

	};

	private HttpUtilProxy() {
		client = HttpClients.custom().setConnectionManager(cm).setKeepAliveStrategy(keepAliveStrat).build();
	}

	public static void IdleConnectionMonitor() {

		if (System.currentTimeMillis() - startTime > 30000) {
			startTime = System.currentTimeMillis();
			cm.closeExpiredConnections();
			cm.closeIdleConnections(30, TimeUnit.SECONDS);
		}
	}

	private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000)
			.setConnectionRequestTimeout(20000).build();

	public static HttpUtilProxy getInstance() {
		return instance;
	}

	public HttpClient getHttpClient() {
		return client;
	}

	private HttpPost httpPostMethod(String url) {
		return new HttpPost(url);
	}

	private HttpRequestBase httpGetMethod(String url) {
		return new HttpGet(url);
	}

	public String get(String url, Map<String, String> header, boolean isproxy) throws Exception {
		CloseableHttpClient httpclient = HttpClients.createDefault();

		try {
			RequestConfig config = null;
			if (isproxy) {
				//
				// ips = IPPoolMap.getQueue().take();
				//
				// Calendar beforeTime = Calendar.getInstance();
				// beforeTime.add(Calendar.MINUTE, -4);// 5分钟之前的时间
				//
				// Date be = beforeTime.getTime();
				// while (be.after(ips.getCreate_time())) {
				// ips = IPPoolMap.getQueue().take();
				// }
				// String host = ips.getIps().split(":")[0];
				// Integer port = Integer.parseInt(ips.getIps().split(":")[1]);
				//
				 HttpHost proxy = new HttpHost("127.0.0.1", 1070, "http");
				 config = RequestConfig.custom().setProxy(proxy).build();

			}

			HttpGet httpGet = new HttpGet(url);
			httpGet.setConfig(config);

			if (header != null) {
				Set<String> keys = header.keySet();
				for (String key : keys) {
					httpGet.setHeader(key, header.get(key));
				}
			}
			// 设置参数到请求对象中

			// System.out.println("Executing request " +
			// request.getRequestLine() + " to " + target + " via " + proxy);
			CloseableHttpResponse response = httpclient.execute(httpGet);
			try {
				int statusCode = response.getStatusLine().getStatusCode();
				// System.out.println("----------------------------------------");
				if (statusCode == 200) {
					String result = EntityUtils.toString(response.getEntity());

					return result;
				} else {
					logger.error("返回状态码异常:" + statusCode);
					return null;
				}

			} catch (Exception e) {
				logger.error("", e);
				return null;

			} finally {

				response.close();
			}
		} catch (Exception e) {

			return null;
		} finally {
			httpclient.close();
		}
	}

	public String requestHttpGet(String url_prex, String url, String param) throws HttpException, IOException {

		IdleConnectionMonitor();
		url = url_prex + url;
		if (param != null && !param.equals("")) {
			if (url.endsWith("?")) {
				url = url + param;
			} else {
				url = url + "?" + param;
			}
		}
		HttpRequestBase method = this.httpGetMethod(url);
		method.setConfig(requestConfig);
		HttpResponse response = client.execute(method);
		HttpEntity entity = response.getEntity();
		if (entity == null) {
			return "";
		}
		InputStream is = null;
		String responseData = "";
		try {
			is = entity.getContent();
			responseData = IOUtils.toString(is, "UTF-8");
		} finally {
			if (is != null) {
				is.close();
			}
		}
		return responseData;
	}

	public String post(String url,String params,boolean ifProxy) throws IOException {

		IdleConnectionMonitor();
		RequestConfig config=null;
		if (ifProxy){
			//加代理,本地测试用
			HttpHost proxy = new HttpHost("127.0.0.1", 1070, "http");
			config = RequestConfig.custom().setProxy(proxy).build();
		}
//		logger.info("参数 >>> "+params);
		HttpPost method = this.httpPostMethod(url);
		method.setHeader("Content-Type","application/json");
		method.setHeader("Accept-Language","zh-cn");
		method.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36");
		method.setEntity(new StringEntity(params));
		method.setConfig(config);
//		System.out.println(method);

		//System.out.println("content >>> "+method.getEntity().getContent());
		HttpResponse response = client.execute(method);
		HttpEntity entity = response.getEntity();
		if (entity == null) {
			return "";
		}
		InputStream is = null;
		String responseData = "";
		try {
			is = entity.getContent();
			responseData = IOUtils.toString(is, "UTF-8");
		} finally {
			if (is != null) {
				is.close();
			}
		}
		return responseData;

	}

	public String requestHttpPost(String url, Map<String, String> params,boolean ifProxy)
			throws HttpException, IOException {
		IdleConnectionMonitor();
		HttpPost method = this.httpPostMethod(url);
		List<NameValuePair> valuePairs = this.convertMap2PostParams(params);
		UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(valuePairs, Consts.UTF_8);
		method.setEntity(urlEncodedFormEntity);

		RequestConfig config=null;
		if (ifProxy){
			//加代理,本地测试用
			HttpHost proxy = new HttpHost("127.0.0.1", 1070, "http");
			config = RequestConfig.custom().setProxy(proxy).build();
		}

		method.setConfig(config);
		HttpResponse response = client.execute(method);
		System.out.println("请求："+method.getURI());
		HttpEntity entity = response.getEntity();

		if (entity == null) {
			return "";
		}
		InputStream is = null;
		String responseData = "";
		try {
			is = entity.getContent();
			responseData = IOUtils.toString(is, "UTF-8");
		} finally {
			if (is != null) {
				is.close();
			}
		}
		return responseData;

	}

	private List<NameValuePair> convertMap2PostParams(Map<String, String> params) {
		List<String> keys = new ArrayList<String>(params.keySet());
		if (keys.isEmpty()) {
			return null;
		}
		int keySize = keys.size();
		List<NameValuePair> data = new LinkedList<NameValuePair>();
		for (int i = 0; i < keySize; i++) {
			String key = keys.get(i);
			String value = params.get(key);
			data.add(new BasicNameValuePair(key, value));
		}
		return data;
	}

	public String doRequest(String api, String requestType, String url, Map<String, String> arguments)
			throws HttpException, IOException {

		List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();

		Mac mac = null;
		SecretKeySpec key = null;

		String postData = "";

		for (Iterator<Entry<String, String>> argumentIterator = arguments.entrySet().iterator(); argumentIterator
				.hasNext();) {

			Entry<String, String> argument = argumentIterator.next();

			urlParameters.add(new BasicNameValuePair(argument.getKey().toString(), argument.getValue().toString()));

			if (postData.length() > 0) {
				postData += "&";
			}

			postData += argument.getKey() + "=" + argument.getValue();

		}

		// Create a new secret key
		try {
			key = new SecretKeySpec(SECRET.getBytes("UTF-8"), "HmacSHA512");
		} catch (UnsupportedEncodingException uee) {
			System.err.println("Unsupported encoding exception: " + uee.toString());
		}

		try {
			mac = Mac.getInstance("HmacSHA512");
		} catch (NoSuchAlgorithmException nsae) {
			System.err.println("No such algorithm exception: " + nsae.toString());
		}

		try {
			mac.init(key);
		} catch (InvalidKeyException ike) {
			System.err.println("Invalid key exception: " + ike.toString());
		}

		// add header
		Header[] headers = new Header[2];
		headers[0] = new BasicHeader("Key", KEY);
		headers[1] = new BasicHeader("Sign", Hex.encodeHexString(mac.doFinal(postData.getBytes("UTF-8"))));

		HttpClient client = HttpClientBuilder.create().build();
		HttpPost post = null;
		HttpGet get = null;
		HttpResponse response = null;

		if (requestType == "post") {
			post = new HttpPost(url);
			post.setEntity(new UrlEncodedFormEntity(urlParameters));
			post.setHeaders(headers);
			response = client.execute(post);
		} else if (requestType == "get") {
			get = new HttpGet(url);
			get.setHeaders(headers);
			response = client.execute(get);
		}

		HttpEntity entity = response.getEntity();
		if (entity == null) {
			return "";
		}
		InputStream is = null;
		String responseData = "";

		is = entity.getContent();
		responseData = IOUtils.toString(is, "UTF-8");
		return responseData;

	}

}
